package com.lovely3x.versionchecklibrary;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;

import com.lovely3x.common.versioncontroller.ApplicationUtils;
import com.lovely3x.common.versioncontroller.Version;
import com.lovely3x.jobservice.JobServiceManager;
import com.lovely3x.jobservice.executors.extensions.downloader2.DownloadTask;
import com.lovely3x.jobservice.executors.extensions.downloader2.executor.DownloadTaskExecutor;
import com.lovely3x.jobservice.executors.extensions.downloader2.utils.DownloadUtils;
import com.lovely3x.jobservice.executors.extensions.version.VersionCheckTask;
import com.lovely3x.jobservice.executors.extensions.version.executor.VersionCheckProgress;
import com.lovely3x.jobservice.executors.extensions.version.factory.VersionCheckFactory;
import com.lovely3x.jobservice.task.Progress;
import com.lovely3x.jobservice.task.Task;

import java.io.File;
import java.util.HashMap;
import java.util.Random;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * 版本检查器
 * Created by lovely3x on 16-2-18.
 */
public class VersionChecker extends JobServiceManager.SimpleJobServiceListener {

    private static VersionChecker INSTANCE = new VersionChecker();

    private String mUrl;
    private Context mContext;
    private long mVersionCheckWhat;
    private long mNewVersionDownloadWhat = 10323;
    /**
     * 是否是静默安装
     */
    private boolean silent;
    private LinkedBlockingQueue<VersionCheckListener> mListeners = new LinkedBlockingQueue<VersionCheckListener>();
    private Version mRemoteVersion;
    private File mDownloadFile;

    private VersionChecker() {
    }

    public static VersionChecker getInstance() {
        return INSTANCE;
    }

    /**
     * like this  "http://121.41.36.153:8080/liumujr/version/version_msg.xml"
     *
     * @param context
     * @param url
     */
    public void check(Context context, String url) {
        this.mUrl = url;
        silent = false;
        this.mContext = context;
        JobServiceManager jsm = JobServiceManager.getInstance();
        jsm.init(context);
        jsm.registerJobServiceListener(this);
        //如果已经创建
        if (jsm.jobServiceIsCreated()) {
            onServiceInitialized();
        }
    }


    /**
     * like this  "http://121.41.36.153:8080/liumujr/version/version_msg.xml"
     *
     * @param context
     * @param url
     */
    public void silentCheck(Activity context, String url) {
        this.mUrl = url;
        this.mContext = context;
        this.silent = true;
        JobServiceManager jsm = JobServiceManager.getInstance();
        jsm.init(context);
        jsm.registerJobServiceListener(this);
        //如果已经创建
        if (jsm.jobServiceIsCreated()) {
            onServiceInitialized();
        }
    }

    @Override
    public void onServiceInitialized() {
        this.mVersionCheckWhat = System.nanoTime() + new Random(Long.MAX_VALUE).nextLong();
        VersionCheckTask task = new VersionCheckTask(mVersionCheckWhat, System.currentTimeMillis(), VersionCheckFactory.EXECUTOR_TYPE, 0, mUrl);
        JobServiceManager.getInstance().addTask(task);
    }

    @Override
    public void onProgress(HashMap<Task, Progress> progresses) {

    }

    @Override
    public void onTaskExecuted(Task task, Exception e, Progress progress) {
        //如果版本检查任务
        if (task.getWhat() == mVersionCheckWhat) {
            if (e == null) {
                VersionCheckProgress vcp = (VersionCheckProgress) progress;
                this.mRemoteVersion = vcp.getRemoteVersion();
                boolean isLatest = ApplicationUtils.isLatestVersion(vcp.getRemoteVersion(), vcp.getLocVersion());
                if (!isLatest) {
                    for (VersionCheckListener listener : mListeners)
                        listener.onNewVersionFound(this, vcp.getLocVersion(), vcp.getRemoteVersion(), vcp.getRemoteVersion().isForceUpdate());
                    //移除掉任务
                    JobServiceManager.getInstance().removeTask(task.getWhat());
                    if (silent) {//如果是静默下载安装
                        JobServiceManager.getInstance().removeTask(mNewVersionDownloadWhat);
                        mDownloadFile = ApplicationUtils.getNewVersionDownloadFile(mContext, vcp.getRemoteVersion());
                        JobServiceManager.getInstance().addTask(new DownloadTask(vcp.remoteVersion.getUrl(), mDownloadFile
                                .getAbsolutePath(),
                                DownloadUtils.REQUEST_METHOD_GET, DownloadTaskExecutor.SINGLE_DOWNLOAD_THREAD,
                                mNewVersionDownloadWhat, DownloadTaskExecutor.EXECUTOR_TYPE));
                    } else {
                        //解除监听器
                        //因为任务都已经转移到Activity中了
                        JobServiceManager.getInstance().unregisterJobServiceListener(this);

                        //显示对话框提示用户更新
                        Intent intent = new Intent(mContext, FoundNewVersionActivity.class);
                        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                        intent.putExtra(FoundNewVersionActivity.EXTRA_VERSION, vcp.getRemoteVersion());
                        mContext.startActivity(intent);
                    }
                } else {
                    for (VersionCheckListener listener : mListeners)
                        listener.onLatestVersion(this, vcp.getLocVersion(), vcp.getRemoteVersion());

                }
            } else {
                for (VersionCheckListener listener : mListeners)
                    listener.onVersionCheckFailure(this, e);
            }

        } else if (task.getWhat() == mNewVersionDownloadWhat) {
            if (e == null) {//下载成功
                JobServiceManager.getInstance().removeTask(task.getWhat());
                //提示用户 已经下载成功
                Intent intent = new Intent(mContext, SilentDownloadedActivity.class);
                intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                intent.putExtra(SilentDownloadedActivity.EXTRA_VERSION, mRemoteVersion);
                intent.putExtra(SilentDownloadedActivity.EXTRA_DOWNLOADED_FILE_PATH, mDownloadFile.getAbsolutePath());
                mContext.startActivity(intent);
                JobServiceManager.getInstance().unregisterJobServiceListener(this);
            } else {//下载失败
                //Resume task to re-download
                //download failure
                JobServiceManager.getInstance().resumeTask(task.getWhat());
            }
        }
    }

    /**
     * 注册版本检查监听器
     *
     * @param versionCheckListener 需要注册的版本监听器
     */
    public void registerVersionCheckListener(VersionCheckListener versionCheckListener) {
        if (versionCheckListener != null) {
            mListeners.add(versionCheckListener);
        }
    }

    /**
     * 解除版本检查监听器
     *
     * @param versionCheckListener 监听器
     */
    public void unregisterVersionCheckListener(VersionCheckListener versionCheckListener) {
        if (versionCheckListener != null) {
            mListeners.remove(versionCheckListener);
        }
    }

    /**
     * 当更新提示对话框Dismiss后执行
     */
    public void onUpdateDialogDismiss(Version remoteVersion) {
        for (VersionCheckListener versionCheckListener : mListeners) {
            versionCheckListener.onUpdateDialogDismissed(this, remoteVersion);
        }
    }


    /**
     * 版本检查监听器
     */
    public interface VersionCheckListener {

        void onUpdateDialogDismissed(VersionChecker vc, Version remoteVersion);

        /**
         * 已经是最新版本
         *
         * @param locVersion    本地版本
         * @param remoteVersion 服务器的版本
         */
        void onLatestVersion(VersionChecker vc, Version locVersion, Version remoteVersion);

        /**
         * 发现新版本
         *
         * @param locVersion    本地版本
         * @param remoteVersion 远程版本
         * @param forceUpdate   是否是强制更新
         */
        void onNewVersionFound(VersionChecker vc, Version locVersion, Version remoteVersion, boolean forceUpdate);


        /**
         * 当新版本检查失败
         *
         * @param e 异常原因
         */
        void onVersionCheckFailure(VersionChecker vc, Exception e);

    }
}
